package top.jfunc.common.router;


import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * LRU(Least Recently Used)：最近最久未使用，时间
 */
public class LRURouter<T, O> implements Router<T, O> {

    private LinkedHashMap<T, T> lruMap;
    private static long CACHE_VALID_TIME = 0;

    @Override
    public T select(List<T> toSelectedList, O otherParam) {
        return route(toSelectedList, otherParam);
    }

    public T route(List<T> toSelectedList, O otherParam) {

        // cache clear
        if (System.currentTimeMillis() > CACHE_VALID_TIME) {
            CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24;
            /**
             * LinkedHashMap
             *      a、accessOrder：true=访问顺序排序（get/put时排序）；false=插入顺序排期；
             *      b、removeEldestEntry：新增元素时将会调用，返回true时会删除最老元素；可封装LinkedHashMap并重写该方法，比如定义最大容量，超出是返回true即可实现固定长度的LRU算法；
             */
            lruMap = new LinkedHashMap<>(16, 0.75f, true);
        }

        // put new
        for (T t: toSelectedList) {
            if (!lruMap.containsKey(t)) {
                lruMap.put(t, t);
            }
        }
        // remove old
        List<T> delKeys = new ArrayList<>();
        for (T existKey: lruMap.keySet()) {
            if (!toSelectedList.contains(existKey)) {
                delKeys.add(existKey);
            }
        }
        if (delKeys.size() > 0) {
            for (T delKey: delKeys) {
                lruMap.remove(delKey);
            }
        }

        // load
        T eldestKey = lruMap.entrySet().iterator().next().getKey();
        return lruMap.get(eldestKey);
    }
}
